package net.majodali.glasshouse.javacode;

import java.lang.reflect.Method;
import java.util.Arrays;

public class MethodSignature {
    private final String name;
    private final Class<?>[] parameterTypes;
    private Class<?> returnType = Void.TYPE;

    public MethodSignature(Method method) {
        name = method.getName();
        parameterTypes = method.getParameterTypes();
        returnType = method.getReturnType();
    }

    public MethodSignature(String name, Class<?>... parameterTypes) {
        this.name = name;
        this.parameterTypes = parameterTypes;
    }

    public String getName() {
        return name;
    }

    public Class<?>[] getParameterTypes() {
        return parameterTypes;
    }

    public Class<?> getReturnType() {
        return returnType;
    }

    boolean matches(Method method) {
        return matches(method.getName(), method.getParameterTypes());
    }

    boolean matches(String name, Class<?>... paramTypes) {
        if (!this.name.equals(name)
                || parameterTypes.length != paramTypes.length)
            return false;
        for (int i = 0; i < paramTypes.length; i++)
            if (!paramTypes[i].isAssignableFrom(parameterTypes[i]))
                return false;
        return true;
    }

    @Override
    public int hashCode() {
        return name.hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof MethodSignature)
            return matches(((MethodSignature) obj).name,
                    ((MethodSignature) obj).parameterTypes)
                    && ((MethodSignature) obj).matches(name, parameterTypes);
        else
            return false;
    }

    @Override
    public String toString() {
        return name
                + Arrays.asList(parameterTypes).toString().replace('[', '(').replace(
                        ']', ')');
    }
}